/**
 * Sensor Network Development Kit for 1-Wire Network (SeN)
 * Version : 0.1
 * Revision date : 2008-10-13
 * Author: Dubravko Penezic, dpenezic@gmail.com
 */
package owExample;

import java.util.Date;
import java.util.Enumeration;
import java.io.*;

import com.dalsemi.onewire.*;
import com.dalsemi.onewire.adapter.*;
import com.dalsemi.onewire.container.*;
import owLib.*;

/**
 * SearchForDevice class do some search over communication adapter with activating all hub/coupler founded on 1-Wire network
 * Version : 0.1.1
 * Revision date : 2008-10-13
 * 
 * @author Dubravko Penezic, dpenezic@gmail.com
 *
 * Based on T. Bitson, SimpleWeather, SimpleWeather.java, 2007
 */
public class SearchForDevice
{
  
  private DSPortAdapter adapter;
  private static OWConf c;
  public OneWireContainer[] owd;
  public varOWDS[] owds;
  
  /**
   *  Finding and init communication adapter and reset 1-Wire bus 
   */  
  public SearchForDevice()
  {
    // get the 1-wire adapter
    try
    {
      // get an instance of the 1-Wire adapter
      adapter = OneWireAccessProvider.getAdapter(c.ONE_WIRE_ADAPTER_TYPE, c.ONE_WIRE_SERIAL_PORT);
      if (adapter != null)
      {
        System.out.println("Found Adapter: " + adapter.getAdapterName() +
                " on Port " + adapter.getPortName());
      }
      else
      {
        System.out.println("Error: Unable to find 1-Wire adapter!");
        System.exit(1);
      }
      
      
      // reset the 1-Wire bus
      resetBus();
    }
    catch (OneWireException e)
    {
      System.out.println("Error Finding Adapter: "+ e);
      System.exit(1);
    }
    
  }
  
  /**
   * mainLoop is thread service , do loop checking if minute is change
   */  
  public void mainLoop()
  {
    Date date = new Date();
    int minute, lastMinute = -99;
    boolean quit = false;
    InputStreamReader in = new InputStreamReader(System.in);
    OWHub h;

    while(!quit)
    {
      // sleep for 1 second
      try
      {
        Thread.sleep(1000);
      }
      catch (InterruptedException e)
      {}
      
      // check current time
      date.setTime(System.currentTimeMillis());
      minute = date.getMinutes();
      
      
      // only loop if a minute is change
      if (minute != lastMinute)
      {
        System.out.println("Time = " + date);
        
        try
        {

           adapter.beginExclusive(true);

           // clear any previous search restrictions
           adapter.setSearchAllDevices();
           adapter.targetAllFamilies();
           adapter.setSpeed(adapter.SPEED_REGULAR);
           
           owds = new varOWDS[0];
           
           SearchOneWireNetwork(adapter);
           RevideOWDS("root","main");

           for(int i = 0; i < owds.length; i++){
      		   if(owds[i].owC.getName().equals("DS2409")){
         		  h = new OWHub(adapter,owds[i].owC.getAddressAsString());
         		  h.deactivateAllPorts();
        		  h.activatePort("main");
                  SearchOneWireNetwork(adapter);
                  RevideOWDS(owds[i].owC.getAddressAsString(),"main");
        		  h.deactivatePort("main");
        		  h.activatePort("aux");
                  SearchOneWireNetwork(adapter);
                  RevideOWDS(owds[i].owC.getAddressAsString(),"aux");
        		  h.deactivatePort("aux");		  		        			   
      		   }
      	   }
  	  
     	  for(int i = 0; i < owds.length; i++)
		     System.out.println(owds[i].owC.getAddressAsString()+" -> "+owds[i].owC.getName()+"("+owds[i].owC.getAlternateNames()+")   ["+owds[i].cAddress+":"+owds[i].cPort+"]");

           adapter.endExclusive();

        }
        catch (Exception e)
        {
           System.out.println(e);
        }
        
        System.out.println("\n");
        
        // update the time
        lastMinute = minute;
      }
      
      // development use only - check for 'q' key press
      try
      {
        if (in.ready())
          if (in.read() == 'q')
          {
            quit = true;
        
            try
            {
              adapter.freePort();
            }
            catch (OneWireException e)
            {
              System.out.println("Error Finding Adapter: "+ e);
            }
			   }
      }
      catch (IOException e)
      { } 
    }
  }
  
  
  /**
   * main start main program and test input parameters if exist, start thread service
   *    
   * @param args
   */
  public static void main(String[] args)
  {
    System.out.println("Starting " + c.VERSION);
    
    if (args.length != 0)
    {
      if (args[0].equals("-d"))
      {
        System.out.println("debug on");
        c.debugFlag = true;
      }
    }
    
    try
    {

      SearchForDevice loopServer   = new SearchForDevice();
      
      // call the main program loop
      loopServer.mainLoop();
    }
    catch(Throwable t)
    {
      System.out.println("Exception: Main() " + t);
    }
    finally
    {
      System.out.println(c.VERSION+" Stopped");
      System.exit(0);
    }
  }
  
  
/**
 * resetBus method try to reset 1-Wire bus
 *     
*/  
  private void resetBus() // reset the 1-wire bus
  {
    System.out.println("Resetting 1-wire bus");
    
    try
    {
      int result = adapter.reset();
      
      if (result == 0)
        System.out.println("Warning: Reset indicates no Device Present");
      if (result == 3)
        System.out.println("Warning: Reset indicates 1-Wire bus is shorted");
    }
    catch (OneWireException e)
    {
      System.out.println("Exception Resetting the bus: " + e);
    }
  }

/**
 * SearchOneWireNetwork method search for 1-Wire device on active part of 1-Wire network which are connected via adapter
 *  
 * @param adapter
 */
  public void SearchOneWireNetwork(DSPortAdapter adapter){

	  owd = new OneWireContainer[0];
      // enumerate through all the 1-Wire devices found
      try {
		for (Enumeration owd_enum = adapter.getAllDeviceContainers(); owd_enum.hasMoreElements(); )
		  {
		     AddToowd(( OneWireContainer ) owd_enum.nextElement());

		  }
	} catch (OneWireIOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (OneWireException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}

  }
 
/**
 * AddToowd method add device on end of list of 1-Wire device founded in last search on active part of 1-Wire network
 * 
 * @param owc
 */
  public void AddToowd(OneWireContainer owc){
	  
	  OneWireContainer[] tmp = new OneWireContainer[owd.length];
	  
	  for(int i = 0; i < owd.length; i++)
			tmp[i] = owd[i];

      owd = new OneWireContainer[owd.length+1];	  

	  for(int i = 0; i < tmp.length; i++)
			owd[i] = tmp[i];
	  
	  owd[tmp.length] = owc ;

  }
 
/**
 * AddToowds method add new device on end of list of founded 1-Wire device
 * 
 * @param owC
 * @param cAddress
 * @param cPort
 */
  public void AddToowds(OneWireContainer owC, String cAddress, String cPort){

	  varOWDS[] tmp = new varOWDS[owds.length];
	  varOWDS tmpv = new varOWDS();
	  
	  for(int i = 0; i < owds.length; i++)
			tmp[i] = owds[i];

      owds = new varOWDS[owds.length+1];	  

	  for(int i = 0; i < tmp.length; i++)
			owds[i] = tmp[i];

	  tmpv.owC = owC ;
	  tmpv.cAddress = cAddress ;
	  tmpv.cPort = cPort ;
	  owds[tmp.length] = tmpv;

  }

/**
 * RevideOWDS method check if last search over active part of 1-Wire network found any new device, and if so add it to list of device.
 * input parameters describe last activated hub/coupler and corresponding port
 * 
 * @param cAddress - hex address string of last activated hub/coupler
 * @param cPort - string name of port ("main", "aux")
 */
  public void RevideOWDS(String cAddress, String cPort){
	  
	  for(int i = 0; i < owd.length; i++){
		  boolean newc = true;
		  for(int j = 0; j < owds.length; j++)
			  if(owd[i].getAddressAsString().equals(owds[j].owC.getAddressAsString())){
				  newc = false;
				  break;
			  }
		  if(newc) AddToowds(owd[i], cAddress, cPort);
	  }
	  
  }
}

